const EventEmitter = require('events');
const fs = require('fs');
const path = require('path');
const { DownloadStatus, isFinishStatus } = require('../../common/DownloadStatus');
const logger = require('../utils/logger');
const UserStopError = require('./errors/UserStopError');

class BaseDownloader extends EventEmitter {
    constructor(options) {
        super();
        this.id = options.id || Date.now();
        this.url = options.url;
        this.headers = options.headers || {};
        this.dir = options.dir;
        this.taskName = options.taskName || `${this.id}`;
        this.status = DownloadStatus.Init;
        this.progress = 0;
        this._stopRequested = false;
    }

    ensureDownloadDir() {
        if (!fs.existsSync(this.dir)) {
            fs.mkdirSync(this.dir, { recursive: true });
        }
    }

    wrapAsyncTaskWithStopCheck(task, stopCallback) {
        if (!task) {
            return;
        }
        if (typeof task !== 'function') {
            throw new Error('Task must be a function');
        }
        return async (...args) => {
            if (this.shouldStop()) {
                if (typeof stopCallback === 'function') {
                    stopCallback();
                }
                throw new UserStopError();
            }
            return await task.apply(this, args);
        };
    }

    

    emitProgress(progress) {
        if (isFinishStatus(this.status) || this.status === DownloadStatus.Stopping) {
            console.debug('已经为结束或停止中状态，不再更新进度', progress);
            return;
        }
        this.progress = progress;
        console.debug('触发进度...');
        this.emit('progress', progress);
    }

    emitComplete(filePath) {
        this.status = DownloadStatus.Success;
        this.emit('complete', {
            outputPath: filePath,
        });
    }

    emitError(err) {
        if (isFinishStatus(this.status)) {
            console.debug('已经为结束状态，不再触发其他异常事件', err);
            return;
        }
        this.status = DownloadStatus.Error;
        console.debug('触发错误...');
        this.emit('error', err);
    }

    async start() {
        throw new Error('start() must be implemented by subclass');
    }

    stop() {
        if (this._stopRequested) return false;
        this._stopRequested = true;
        // 先更新进度
        this.emitProgress({
            status: 'stopping',
            message: 'Stopping...',
            stage: 'stopping',
        });
        this.status = DownloadStatus.Stopped;
        return true;
    }

    shouldStop() {
        return this._stopRequested;
    }

    resetStopFlag() {
        this._stopRequested = false;
    }
}

module.exports = { BaseDownloader };
